/**
 * 
 */
package com.zhiteng.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.zhiteng.entity.AdjustBill;
import com.zhiteng.entity.Assignee;
import com.zhiteng.entity.Bill;
import com.zhiteng.entity.LeaveBill;
import com.zhiteng.entity.Procdef;
import com.zhiteng.entity.Procins;
import com.zhiteng.entity.Teacher;
import com.zhiteng.service.ActualNodeService;
import com.zhiteng.service.AdjustBillService;
import com.zhiteng.service.AssigneeService;
import com.zhiteng.service.LeaveService;
import com.zhiteng.service.ProcdefService;
import com.zhiteng.service.ProcessService;
import com.zhiteng.service.TeacherService;
import com.zhiteng.utils.common.ZTResult;
import com.zhiteng.vo.ProcinsVo;

/**
 * <p>
 * Title: CommonProcessController.java
 * </p>
 * <p>
 * Description: 请假、调课、代课 公共Controller
 * </p>
 * 
 * @author dragon
 * @date 2018年12月13日
 * @version 1.0
 */
@RequestMapping("/commonProcess")
@Controller
public class CommonProcessController {
	@Autowired
	private ProcessService processService;
	@Autowired
	private LeaveService leaveService;

	@Autowired
	private AdjustBillService adjustBillService;

	@Autowired
	private ProcessService processServiceImpl;
	@Autowired
	private ActualNodeService ActualNodeService;

	@Autowired
	private ProcdefService ProcdefServiceImpl;
	@Autowired
	private TeacherService teacherService;
	@Autowired
	private AssigneeService assigneeService;

	/**
	 * 
	 * @Title: queryLeaveBills
	 * @Description: 我的提交：查询我的所有申请单
	 * @param          teacherId(前端传入登录用户的usrid,对应tb_leavebill表中的teacher_id)
	 * @param schoolId
	 */
	@RequestMapping("/queryMyCommit")
	@ResponseBody
	public ZTResult<Object> queryMyCommit(@RequestParam(name = "teacherId") String teacherId,
			@RequestParam(name = "schoolId") String schoolId) {

		if (StringUtils.isAnyBlank(teacherId, schoolId)) {
			return ZTResult.result(1, "查询失败，教师id不能为空");
		}
		List<Bill> billList = new ArrayList<>(); // 用于封装返回的结果
		// 1、查询我提交的请假单
		List<LeaveBill> leaveBillList = leaveService.queryLeaveBillsByTeacherIdAndSchoolId(teacherId, schoolId);
		if (leaveBillList != null && !leaveBillList.isEmpty()) {
			for (LeaveBill bill : leaveBillList) {
				if (bill.getCreateDate() != null) {
					Bill b = new Bill(bill.getCreateDate());
					b.setId(bill.getId());
					b.setReason(bill.getReason());
					b.setStatus(bill.getStatus());
					b.setTeacherName(bill.getTeacherName());
					b.setRevocable(bill.getRevocable());
					b.setType(bill.getType());
					b.setStart(bill.getStart());
					b.setEnd(bill.getEnd());
					b.setHours(bill.getTotal_hour());
					billList.add(b);
				}
			}
		}

		// 2.查询调课和代课
		List<AdjustBill> AdjustBillList = adjustBillService.queryAdjustBillByTeacherId(teacherId);
		if (AdjustBillList != null && !AdjustBillList.isEmpty()) {
			for (AdjustBill bill : AdjustBillList) {
				if (bill.getCreateDate() != null) {
					Bill b = new Bill(bill.getCreateDate());
					b.setId(bill.getId());
					b.setReason(bill.getReason());
					b.setStatus(bill.getStatus());
					b.setTeacherName(bill.getTeacher_name());
					b.setRevocable(bill.getRevocable());
					b.setType(bill.getType2() + 1);
					b.setWeek(bill.getWeek());
					b.setOldNode(bill.getOld_node());
					billList.add(b);
				}
			}
		}

		Collections.sort(billList);

		return ZTResult.result(0, "查询成功", billList);
	}

	/**
	 * 
	 * @Title: showLeaveBillById
	 * @Description: 我的提交中点击某个请假单后根据请假单id查询请假单和请假流程实例
	 * @param billId 申请单id
	 * @param type   1.请假 2.调课 3.代课
	 * @return complated:0-审批中 1-审批通过 2-审批驳回
	 */
	@RequestMapping("/queryBillAndProcess")
	@ResponseBody
	public ZTResult<Map<String, Object>> queryBillAndProcess(@RequestParam(name = "billId") long billId,
			@RequestParam(name = "type") int type) {

		if (StringUtils.isAnyBlank(billId + "", type + "")) {
			return ZTResult.result(1, "查询失败，请检查参数");
		}

		Map<String, Object> resultMap = new HashMap<>(); // 用于封装返回的结果

		if (type == 1) { // 请假单
			// 查询请假单
			LeaveBill leaveBill = leaveService.queryLeaveBillById(billId);
			if (leaveBill == null)
				return ZTResult.result(1, "未查询到该申请单");
			// 包装成bill返回给前台
			Bill bill = new Bill();
			bill.setType(leaveBill.getType());
			bill.setTeacherName(leaveBill.getTeacherName());
			bill.setTeacherId(leaveBill.getTeacher_id());
			bill.setStatus(leaveBill.getStatus());
			bill.setStart(leaveBill.getStart());
			bill.setEnd(leaveBill.getEnd());
			bill.setHours(leaveBill.getTotal_hour());
			bill.setReason(leaveBill.getReason());
			bill.setCreateDate(leaveBill.getCreateDate());

			// 根据请假单id查询流程实例（type=1）
			List<Procins> procinsList = processService.queryProcinsByBillId(billId); // 查询的结果是根据sequence升序排序的
			List<ProcinsVo> procinsVoList = new ArrayList<>();
			for (Procins procins : procinsList) {
				ProcinsVo procinsVo = new ProcinsVo();
				procinsVo.setComplated(procins.getComplated());
				procinsVo.setEnd(procins.getEnd());
				procinsVo.setRemark(procins.getRemark());
				procinsVo.setSequence(procins.getSequence());
				procinsVo.setStatus(procins.getStatus());
				//	ps:不能assigneeService.queryAssigneeId，防止出现后期审批人被删除的情况
				Assignee assignee = assigneeService.queryAssigneeId(procins.getAssignee_id());
				if (assignee != null) {
					procinsVo.setAssigneeName(assignee.getName());
					procinsVo.setRole(assignee.getRole());
				}
				procinsVoList.add(procinsVo);
			}

			resultMap.put("bill", bill);
			resultMap.put("procinsVoList", procinsVoList);
		} else { // 调课单/代课单
			AdjustBill adjustBill = adjustBillService.queryAdjustBillByBillId(billId);
			if (adjustBill == null)
				return ZTResult.result(1, "未查询到该申请单");
			// 包装成bill返回给前台
			Bill bill = new Bill();
			bill.setType(adjustBill.getType2() + 1);
			bill.setTeacherName(adjustBill.getTeacher_name());
			bill.setTeacherId(adjustBill.getTeacher_id());
			bill.setStatus(adjustBill.getStatus());
			bill.setAdjustDate(adjustBill.getAdjust_date());
			bill.setWeek(adjustBill.getWeek());
			bill.setOldNode(adjustBill.getOld_node());
			bill.setPetitionerDate(adjustBill.getPetitioner_date());
			bill.setPetitionerWeek(adjustBill.getPetitioner_week());
			bill.setCourseNum(adjustBill.getCourse_num());
			bill.setPetitionerId(adjustBill.getPetitioner_id()); // 用于判断当前登录用户是被申请老师，还是后面的审批人
			// 若当前登录用户不是被申请老师而是后面的审批人，则页面中需要显示被申请老师的姓名
			Teacher teacher = teacherService.queryTeacherById(adjustBill.getPetitioner_id());
			if (teacher != null)
				bill.setPetitionerName(teacher.getName());
			bill.setCreateDate(adjustBill.getCreateDate());

			List<Procins> procinsList = processService.queryProcinsByBillId2(billId); // 查询的结果是根据sequence升序排序的
			List<ProcinsVo> procinsVoList = new ArrayList<>();
			for (Procins procins : procinsList) {
				ProcinsVo procinsVo = new ProcinsVo();
				procinsVo.setComplated(procins.getComplated());
				procinsVo.setEnd(procins.getEnd());
				procinsVo.setRemark(procins.getRemark());
				procinsVo.setSequence(procins.getSequence());
				procinsVo.setStatus(procins.getStatus());
				// 被申请的老师
				Teacher petitioner = teacherService.queryTeacherById(procins.getPetitioner_id());
				if (petitioner != null) {
					procinsVo.setPetitionerName(petitioner.getName());
					procinsVo.setAssigneeName(petitioner.getName());
				}
				Assignee assignee = assigneeService.queryAssigneeId(procins.getAssignee_id());
				if (assignee != null) {
					procinsVo.setAssigneeName(assignee.getName());
					procinsVo.setRole(assignee.getRole());
				}
				procinsVoList.add(procinsVo);
			}
			resultMap.put("bill", bill);
			resultMap.put("procinsVoList", procinsVoList);
		}

		return ZTResult.result(0, "查询成功", resultMap);
	}

	/**
	 * 
	 * @Title: queryUncomplatedBill
	 * @Description: 查询待我审核的申请单(待我确认)
	 * @param teacherId (此时teacherId就是tb_assignee表中的assignee_id)
	 * @param schoolId  学校id
	 */
	@RequestMapping("/queryMyUncomplatedBills")
	@ResponseBody
	public ZTResult<Object> queryMyUncomplatedBills(@RequestParam(name = "teacherId") String teacherId,
			@RequestParam(name = "schoolId") String schoolId) {
		if (StringUtils.isAnyBlank(teacherId, schoolId)) {
			return ZTResult.result(1, "查询失败，请检查参数");
		}
		List<Bill> billList = new ArrayList<>(); // 用于封装返回的结果
		// 1、查询待我审核的请假单
		List<LeaveBill> leaveBillList = leaveService.queryMyUncomplatedLeaveBills(teacherId, schoolId);
		if (leaveBillList != null && !leaveBillList.isEmpty()) {
			for (LeaveBill bill : leaveBillList) {
				if (bill.getCreateDate() != null) {
					Bill b = new Bill(bill.getCreateDate());
					b.setId(bill.getId());
					b.setReason(bill.getReason());
					b.setTeacherName(bill.getTeacherName());
					b.setType(bill.getType());
					b.setStart(bill.getStart());
					b.setEnd(bill.getEnd());
					b.setHours(bill.getTotal_hour());
					billList.add(b);
				}
			}
		}

		///////////////////////////////////////////////////////////////////////////////////

		// 2、查询待我审核的调课单和代课单
		List<Procins> procinsList = processServiceImpl.queryProcinsByAssigneeId(teacherId);
		if (procinsList != null && !procinsList.isEmpty()) {
			List<AdjustBill> AdjustBillList = new ArrayList<>();
			for (Procins procins : procinsList) {
				AdjustBill adjustBill = adjustBillService.queryAdjustBillByBillId(procins.getBill_id());
				AdjustBillList.add(adjustBill);
			}
			if (AdjustBillList != null && !AdjustBillList.isEmpty()) {
				for (AdjustBill bill : AdjustBillList) {
					if (bill.getCreateDate() != null) {
						Bill b = new Bill(bill.getCreateDate());
						b.setId(bill.getId());
						b.setReason(bill.getReason());
						b.setTeacherName(bill.getTeacher_name());
						b.setPetitionerName(bill.getPetitioner_name());
						b.setType(bill.getType2() + 1);
						b.setWeek(bill.getWeek());
						b.setOldNode(bill.getOld_node());
						b.setPetitionerWeek(bill.getPetitioner_week());
						b.setCourseNum(bill.getCourse_num());
						b.setAdjustDate(bill.getAdjust_date());
						b.setPetitionerDate(bill.getPetitioner_date());

						billList.add(b);
					}
				}
			}
		}
		Collections.sort(billList);

		return ZTResult.result(0, "查询成功", billList);
	}

	/**
	 * 
	 * @Title: toComplatedMyLeaveBill
	 * @Description: 完成申请单的审批（同意或拒绝）
	 * @param status    0为同意，1为拒绝
	 * @param billId    申请单id
	 * @param type      1.请假 2.调课 3.代课
	 * @param schoolId  学校id
	 * @param teacherId 审批人id(登录教师的id)
	 * @param remark    批注（非必须）
	 */
	@RequestMapping("/toComplatedMyBill")
	@ResponseBody
	public ZTResult<Void> toComplatedMyBill(@RequestParam(name = "billId") long billId,
			@RequestParam(name = "teacherId") String teacherId, @RequestParam(name = "schoolId") String schoolId,
			@RequestParam(name = "status") int status, @RequestParam(name = "type") int type,
			@RequestParam(name = "remark", defaultValue = "", required = false) String remark) {

		if (StringUtils.isAnyBlank(teacherId,schoolId)) {
			return ZTResult.result(1, "审批失败，请检查参数");
		}
		if("null".equals(billId + "") || "null".equals(status + "") || "null".equals(type + "")) {
			return ZTResult.result(1, "审批失败，请检查参数");
		}
		if (type == 1) { // 请假单
			leaveService.saveComplatedMyLeaveBill(billId, teacherId, schoolId, status, remark);
		} else { // 调课单/代课单
			/////////////////////////////////////////////////////
			int i = processServiceImpl.updateProcinsStatus(schoolId, billId, status, teacherId, remark);
			if (status == 0 && i != 0) {
				adjustBillService.updateRevocable(billId, 1);// 是否可撤销
			}
			// List<Procdef> list = processServiceImpl.queryProcdefBySchoolId(schoolId);
			List<Procdef> list = ProcdefServiceImpl.queryProcdefBySchoolIdAndType(schoolId, type);
			if (!list.get(list.size() - 1).getAssignee_id().equals(teacherId) && status == 0) {
				List<Procins> Procins = processServiceImpl.queryProcinsBySchoolIdAndAssigneeIdAndBillId(schoolId,
						teacherId, billId);
				for (Procins procins2 : Procins) {
					processServiceImpl.setNextStart(procins2.getSequence() + 1, schoolId, billId);
				}
			}
			if (status == 1 || list.get(list.size() - 1).getAssignee_id().equals(teacherId) && status == 0) {
				processServiceImpl.updateComplated(billId);
			}
			if (status == 1) {
				adjustBillService.updateStatus(billId, 2);// 审批不通过
			}
			if (list.get(list.size() - 1).getAssignee_id().equals(teacherId) && status == 0) {
				int j = adjustBillService.updateStatus(billId, 1);// 审批通过
				if (j != 0) {
					AdjustBill bill = adjustBillService.queryAdjustBillByBillId(billId);
					ActualNodeService.saveActualNode(bill);
				}
			}
			if (i == 0) {
				return ZTResult.result(1, "通过审批人的id,学校的id,调课单的id,状态,来修改状态失败");
			}
		}
		return ZTResult.result(0, "审批成功");
	}

	/**
	 * 
	 * @Title: queryMyComplatedLeaveBill
	 * @Description: 查询我已确认的申请单
	 * @param teacherId 老师id
	 * @param schoolId  学校id
	 */
	@RequestMapping("/queryMyComplatedBills")
	@ResponseBody
	public ZTResult<Object> queryMyComplatedLeaveBill(@RequestParam(name = "teacherId") String teacherId,
			@RequestParam(name = "schoolId") String schoolId) {
		if (StringUtils.isAnyBlank(teacherId, schoolId)) {
			return ZTResult.result(1, "查询失败，请检查参数");
		}

		Set<Bill> allBillList = new HashSet<>();
//		List<Bill> allBillList = new ArrayList<>();
		// 1、查询我已确认的请假单
		List<Bill> leaveBillVoList = leaveService.queryMyComplatedLeaveBill(teacherId, schoolId);
		allBillList.addAll(leaveBillVoList);

		// 2、查询我已确认的调课单和代课单
		List<Procins> list = processServiceImpl.queryAdjustBillByAssigneeId2(teacherId);
		if (list != null && !list.isEmpty()) {
			for (Procins procins : list) {
				AdjustBill adjustBill = adjustBillService.queryAdjustBillByBillId(procins.getBill_id());
				if (adjustBill != null) {
					Bill b = new Bill();
					b.setCreateDate(adjustBill.getCreateDate());
					b.setId(adjustBill.getId());
					b.setReason(adjustBill.getReason());
					b.setTeacherName(adjustBill.getTeacher_name());
					b.setType(adjustBill.getType2() + 1);
					b.setWeek(adjustBill.getWeek());
					b.setOldNode(adjustBill.getOld_node());
					b.setPetitionerWeek(adjustBill.getPetitioner_week());
					b.setCourseNum(adjustBill.getCourse_num());
					b.setIsAgree(procins.getStatus()); // 已同意/已拒绝
					b.setAdjustDate(adjustBill.getAdjust_date());
					b.setPetitionerDate(adjustBill.getPetitioner_date());
					b.setPetitionerName(adjustBill.getPetitioner_name());

					allBillList.add(b);
				}
			}
		}
		List<Bill> list2 = new ArrayList(allBillList);
		Collections.sort(list2);

		return ZTResult.result(0, "查询成功", list2);
	}

	/**
	 * 
	 * @Title: toCancelMyBill @Description: 撤回申请（在第一个审批人审批之前可撤回） @param billId
	 *         申请单id @param teacherId 教师id @param schoolId 学校id @param type 1.请假
	 *         2.调课 3.代课 @return ZTResult<Void> @throws
	 */
	@RequestMapping("/toCancelMyBill")
	@ResponseBody
	public ZTResult<Void> toCancelMyBill(@RequestParam(name = "billId") long billId,
			@RequestParam(name = "type") int type) {
		if ("null".equals(billId + "") || "null".equals(billId + "")) {
			return ZTResult.result(1, "撤回失败，请检查参数");
		}
		if (type == 1) { // 撤回请假申请：1.修改leaveBill状态为已撤回 2.删除流程实例 3.通知第一个审批人已撤回
			LeaveBill leaveBill = leaveService.queryLeaveBillById(billId);
			if (leaveBill.getRevocable() == 1) {
				return ZTResult.result(1, "该请假单无法撤回");
			}
			leaveBill.setRevocable(1);
			leaveBill.setStatus(-1); // 已撤回
			leaveService.updateCancleLeaveBill(leaveBill);
		} else { // 撤回调课或代课申请：
			/////////////////////////////////////////////////////////////////////////
			AdjustBill bill = adjustBillService.queryAdjustBillByBillId(billId);
			if (bill.getRevocable() == 1) {
				return ZTResult.result(1, "流程正在审批中不能撤回");
			}

			int updateStatus = adjustBillService.updateStatus(billId, -1);

			if (updateStatus == 0) {
				return ZTResult.result(1, " 撤回失败,传的billId不对");
			}

			int i = processServiceImpl.deleteProcins(billId);
			if (i == 0) {
				return ZTResult.result(1, "删除审批实例流程失败,传的billId不对");
			}
		}
		return ZTResult.result(0, "撤回成功");
	}

	/**
	 * 
	 * @Title: queryBill @Description: 根据调课单/代课单id查询详情（手机端首页课表用） @param billId
	 *         调课单/代课单id @return ZTResult<Bill> @throws
	 */
	@RequestMapping("/queryBill")
	@ResponseBody
	public ZTResult<Bill> queryBill(@RequestParam(name = "billId") long billId) {
		if ("null".equals(billId + "")) {
			return ZTResult.result(1, "查询失败，请检查参数");
		}
		Bill bill = adjustBillService.queryBillById(billId);
		if (bill == null) {
			return ZTResult.result(1, "未查询到相关信息");
		}
		return ZTResult.result(0, "查询成功", bill);
	}
}
